home *** CD-ROM | disk | FTP | other *** search
/ Apple Reference & Presentation Library 1993 Spring / ARPL-Spring-93-Partner-Edition.iso / Applications / Spreadsheets / Claris Resolve Demo / Resolve Samples / External Examples / SndTools.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-07-17  |  21.7 KB  |  787 lines  |  [TEXT/MPS ]

  1. /*Add global strings (tempstr, errstring)  without testing.... check it */
  2. /*#define Debugging 1     Uncomment to debug.  Must change the Project type to APPL*/
  3.  
  4. #ifndef nil
  5.     #define nil 0L
  6. #endif nil
  7. #define ThinkC
  8. #define numfuncs 7            /* The number of external functions in this file */
  9. #include "ThinkCGlue.h"        /* THE HEADER IN THIS FILE MUST BE CHANGED WHENEVER ANY CODE IS ADDED */
  10.                         /*  Note:  The headers sound.h and soundInput.h where in  beta when this code was
  11.                             begin developed.  These files are probably different from what Apple/Symantec
  12.                             is currently shipping. */
  13. #include "sound.h"            
  14. #include "soundInput.h"
  15.  
  16.  
  17. /* constants */
  18. /* STR# rsrc*/
  19. enum {sRoutineNames=5000, sErrStrings, sSMErrStrings};
  20.  
  21. /* STR# items */    
  22. enum  {     siRecordRoutine=1, siDeleteRoutine, siGetQualityRoutine,siSetQualityRoutine, 
  23.         siCopyPICTRoutine,siGetSoundsRoutine,siMySFGetFile};
  24.  
  25. enum { siMemErr=1, siResErr, siNoSoundErr,siWrongRecVersion, siWrongPlayVersion,
  26.     siSoundPlayErr, siSoundRecErr, siFileErr, siNeedClosedSpeadSheet, siAlreadyInUse, 
  27.     siNoSoundErrOrFileErr, siCancelled,siBadQuality};
  28.  
  29. #define kQualID 5000                 /* rsrcID of our quality resource */
  30.  
  31. /*Globals*/
  32. short                gOurResFile;    /* tools rsrc file */
  33. GrafPtr                gOurPort;        /* tools graph port */
  34. OSType                **gQualRsrc;     /* stores the current quality at which to record */
  35. Str255                gGlobalStr;      /* when returning a string to Resolve, the string must be global*/
  36. short                gSndIndex;    /*  used by getSounds() to keep track of next sound when repeatedly*/
  37.  
  38. /*These are our function names that we read in from the rsrc fork.  They must exist in global variables and cannot
  39. be changed after set. */
  40. typedef    char    Str31[32];
  41. Str31    gFuncName[numfuncs]; 
  42.  
  43. /*  MACROS */
  44. #define FILENAME    parg[0].val.string
  45. #define SNDNAME    parg[1].val.string
  46. #define ABS(val)        ((val < 0) ? (-val) : (val))
  47. #define TopLeft(r)        (* (Point *) &(r).top)
  48. #define BotRight(r)        (* (Point *) &(r).bottom)
  49. #define SETPT(pt, x, y)    (*(pt)).h = (x); (*(pt)).v = (y)
  50. #define SETRECT(r, left, top, right, bottom)    \
  51.                         SETPT(&TopLeft(*(r)), (left), (top)); \
  52.                         SETPT(&BotRight(*(r)), (right), (bottom))
  53.  
  54. /* return an error from function to Resolve*/
  55. #define DoErr(num)        {pret[0].flag = ERR;pret[0].val.err =(short) num;RestoreA4();return;}
  56.  
  57. /* Set up an error for returning but don't return */
  58. #define SetErr(num)        {pret[0].flag = ERR;pret[0].val.err = num;}
  59.  
  60. /*  Set up a string for returning but don't return */
  61. #define SetReturnStr(str)    {pret[0].flag = STRING;pret[0].val.string =(char *) StripAddress(str);}
  62.  
  63. #define _Unimplemented    0xA89F        /*traps */
  64. #define _SoundInput        0xA800
  65. #define _SndPlay        0xA805
  66.  
  67.  
  68. Boolean TrapAvailable(short tNumber,short tType){
  69.     return NGetTrapAddress(tNumber, tType) != GetTrapAddress(_Unimplemented);
  70.     }
  71.  
  72. Boolean InputManagerInstalled(void){
  73.     return (( TrapAvailable(_SoundInput, 1)) && (MACEVersion() !=0));
  74.     }
  75.     
  76. Boolean SndPlayInstalled(void){
  77.     return (TrapAvailable(_SndPlay, 1));
  78.     }
  79.  
  80. /******************Window Centering Code *******************/
  81.  
  82. void    PositionTwoRects(Rect outerRect, Rect *innerRect, Fixed horzRatio, Fixed vertRatio){
  83.     short        outerRectHeight;
  84.     short        outerRectWidth;
  85.     short        innerRectHeight;
  86.     short        innerRectWidth;
  87.     short        yLocation;
  88.     short        xLocation;
  89.  
  90.     outerRectHeight = outerRect.bottom - outerRect.top;
  91.     outerRectWidth = outerRect.right - outerRect.left;
  92.  
  93.     innerRectHeight = (*innerRect).bottom - (*innerRect).top;
  94.     innerRectWidth = (*innerRect).right - (*innerRect).left;
  95.         yLocation = Fix2Long (FixMul (Long2Fix (outerRectHeight - innerRectHeight), vertRatio))
  96.             + outerRect.top;
  97.         xLocation = Fix2Long (FixMul (Long2Fix (outerRectWidth - innerRectWidth), horzRatio))
  98.             + outerRect.left;
  99.  
  100.     (*innerRect).top = yLocation;
  101.     (*innerRect).left = xLocation;
  102.     (*innerRect).bottom = yLocation + innerRectHeight;
  103.     (*innerRect).right = xLocation + innerRectWidth;
  104.     }
  105.  
  106.     
  107. /* This procedure is used to get the rectangle that surrounds the entire structure of a
  108.   window, given the rectangle that would be used for the portRect. It does this by
  109.   temporarily creating a window way offscreen, and getting the rgnBBox of its strucRgn.
  110.   The window is disposed of afterwards, and the port set back to the original port. */
  111.  
  112. void    GetWindowStrucRect(short procID, Rect boundsRect, Rect *strucRect){
  113. #define kOffscreenLoc 0x4000
  114.  
  115.     GrafPtr            oldPort;
  116.     WindowPtr        tempWindow;
  117.     Point                offsetAmount;
  118.  
  119.     GetPort(&oldPort);
  120.     SETPT(&offsetAmount, kOffscreenLoc, kOffscreenLoc);
  121.     SubPt(TopLeft(boundsRect), &offsetAmount);
  122.     OffsetRect(&boundsRect, offsetAmount.h, offsetAmount.v);
  123.     tempWindow = NewWindow(nil, &boundsRect, '', true, procID, (WindowPtr)nil, true, 0);
  124.     (*strucRect) = (**(*(WindowPeek)tempWindow).strucRgn).rgnBBox;
  125.     DisposeWindow(tempWindow);
  126.     OffsetRect(strucRect, -offsetAmount.h, -offsetAmount.v);
  127.     SetPort(oldPort);
  128.     }
  129.  
  130.  
  131. void    CenterWindowRectTo (short procID, Rect screenRect, Rect *theRect){
  132.     Point            windowSize;
  133.     Rect            strucRect, newStrucRect;
  134.  
  135.     GetWindowStrucRect(procID, *theRect, &strucRect);
  136.     newStrucRect = strucRect;
  137.     PositionTwoRects(screenRect, &newStrucRect, FixRatio (1, 2), FixRatio (1, 3));
  138.     windowSize = BotRight(*theRect);
  139.     SubPt(TopLeft(*theRect), &windowSize);
  140.     (*theRect).top = newStrucRect.top + ((*theRect).top - strucRect.top);
  141.     (*theRect).left = newStrucRect.left + ((*theRect).left - strucRect.left);
  142.     (*theRect).bottom = (*theRect).top + windowSize.v;
  143.     (*theRect).right = (*theRect).left + windowSize.h;
  144.     }
  145.  
  146. void    CenterWindowRect (short procID, Rect *theRect){
  147.     Rect    screenRect;
  148.     
  149.     screenRect = screenBits.bounds;
  150.     screenRect.top += GetMBarHeight();
  151.     CenterWindowRectTo(procID, screenRect, theRect);
  152.     }
  153.     
  154.  
  155. Point        CenteredDLOG(short ID){
  156.     DialogTHndl            dlogH;
  157.     short                itemHit;
  158.     Point                    pt;                    
  159.  
  160.     dlogH = (DialogTHndl)Get1Resource('DLOG',ID);
  161.     SETPT(&pt,30,40);
  162.     if (dlogH) {
  163.         MoveHHi((Handle)dlogH);
  164.         HLock((Handle)dlogH);
  165.         CenterWindowRect(dBoxProc, &((**dlogH).boundsRect));
  166.         SETPT(&pt,((**dlogH).boundsRect.left),((**dlogH).boundsRect.top));
  167.         HUnlock((Handle)dlogH);
  168.         }
  169.     return (pt);
  170.     }
  171.  
  172. /******************SFResult to FullPathName Code**************/
  173. /* given a working directory, this call returns a volumen and folder */
  174. OSErr SFVolDir(short wd, short *volume, long *folder){
  175.     WDPBRec         pb; 
  176.     unsigned char     name[72];
  177.     
  178.     pb.ioNamePtr = (StringPtr)name;
  179.     pb.ioVRefNum = wd;
  180.     pb.ioWDIndex = 0;
  181.     pb.ioWDProcID = 0;
  182.     pb.ioWDVRefNum = 0;
  183.     PBGetWDInfo(&pb, false);
  184.     if (pb.ioResult) return pb.ioResult;
  185.     *volume = pb.ioWDVRefNum;
  186.     *folder = pb.ioWDDirID;
  187.     return noErr;
  188.     }
  189.     
  190. /*given a filename, volume, and dirId it returns a fullpathname in fullName*/
  191. OSErr FullFileName(StringPtr fullName, StringPtr fName, short volume, long dirID){
  192.     StringHandle     tempName; 
  193.     Str255         text, volname; 
  194.     HVolumeParam     hvp;
  195.     CInfoPBRec     di;
  196.     long             size;
  197.     short         err;
  198.  
  199.     /* extract the volume Name */
  200.     volname[0]='\0';
  201.     hvp.ioNamePtr = volname;
  202.     hvp.ioVRefNum = volume;
  203.     hvp.ioVolIndex = 0;
  204.     PBHGetVInfo((HParmBlkPtr)&hvp, false);
  205.  
  206.     /* create and initialize the name handle */
  207.     if ((tempName = (StringHandle) NewHandle(256)) == 0)
  208.          return MemError();
  209.     BlockMove((Ptr)fName+1,(Ptr)*tempName,fName[0]);
  210.     size = fName[0];
  211.     /* now start extracting the dirs and prepending them to the handle*/
  212.     for ( ; dirID != 2; dirID = di.dirInfo.ioDrParID) {
  213.         text[0] = 0;
  214.         di.dirInfo.ioNamePtr = text;
  215.         di.dirInfo.ioVRefNum = volume;
  216.         di.dirInfo.ioFDirIndex = -1;
  217.         di.dirInfo.ioDrDirID = dirID;
  218.         PBGetCatInfo(&di, false);
  219.         text[++text[0]] = ':';
  220.         SetHandleSize(tempName,size +=text[0]);
  221.         BlockMove((Ptr)*tempName, (Ptr)(*tempName) + text[0], size - text[0]);
  222.         BlockMove((Ptr)text + 1, (Ptr)*tempName, text[0]);
  223.         }
  224.  
  225.     /* prepend the volume name onto the handle */
  226.     volname[++volname[0]] = ':';
  227.     SetHandleSize(tempName, size += volname[0]);
  228.     BlockMove((Ptr)*tempName, (Ptr)(*tempName) + volname[0], size - volname[0]);
  229.     BlockMove((Ptr)volname + 1, (Ptr)*tempName, volname[0]);
  230.  
  231.     /* copy and delete the handle */
  232.     if (size > 255) {
  233.         DisposHandle(tempName);
  234.         SysBeep(12);
  235.         fullName[0] = 0;
  236.         return -1;     /*too big... fail*/
  237.         }
  238.     fullName[0] = size;
  239.     BlockMove((Ptr)*tempName, (Ptr)fullName + 1, size);
  240.     DisposHandle(tempName);
  241.     return noErr;
  242.     }
  243.  
  244. /*simple takes a SFReply and uses it to call SFVolDir and then FullFileName */
  245. void GetFullPathName(SFReply  sf,Str255 fullName){
  246.     short     volume;
  247.     long        folder;
  248.     
  249.     fullName[0]='\0';
  250.     
  251.     if (!SFVolDir(sf.vRefNum, &volume,&folder)) 
  252.         FullFileName((StringPtr)fullName,sf.fName,volume,folder);
  253.     }
  254.  
  255.  
  256. /******************Error handling function ******************/
  257. /* Return an error string to Resolve that is found in the tools STR# rsrc*/
  258. void getErrString(OSErr err,short messageID,Str255 errString){
  259.     short        savedResFile;
  260.     Str255        errNumStr;    
  261.     
  262.     savedResFile=CurResFile();
  263.     UseResFile(gOurResFile);
  264.     
  265.     if (messageID > 0 ){
  266.         GetIndString(errString, sErrStrings, messageID);    
  267.             }
  268.     if (err!=0)
  269.         NumToString(err, errNumStr);
  270.     if (err){ /* combine the strings */
  271.         BlockMove(StripAddress("  Error Nº "),&(errString[errString[0]+1]),11);
  272.         errString[0]+=11;
  273.  
  274.         BlockMove(&(errNumStr[1]),&(errString[errString[0]+1]),errNumStr[0]); 
  275.         errString[0]+=errNumStr[0];
  276.         }
  277.  
  278.     UseResFile(savedResFile);
  279.     }
  280.  
  281. /**********************Delete A Sound From the File ************/
  282. void delete1Sound(StringPtr name,short sndResFile){
  283.     Handle        sndH;
  284.     short        rsrcID;
  285.     OSType        rsrcType;
  286.     short        attribs;
  287.     Str31        tempStr;
  288.  
  289.     SetResLoad(false); /* don't need to load in data to delete it. */
  290.     sndH=(Handle)Get1NamedResource('snd ',name);
  291.     if (sndH){
  292.         GetResInfo(sndH, &rsrcID, &rsrcType, &tempStr);    /* get the rsrcID */
  293.         RmveResource(sndH);                        /* remove it */
  294.         ChangedResource(sndH);
  295.         UpdateResFile(sndResFile);
  296.         attribs=GetResFileAttrs(sndResFile);            /* compact the rsrc file*/
  297.         attribs &= mapCompact;
  298.         SetResFileAttrs(sndResFile,attribs);
  299.         UpdateResFile(sndResFile);
  300.         }
  301.     SetResLoad(true);
  302.     }
  303.     
  304. /********************Tool ROUTINES********************/
  305. /* Dispose of our global stuff*/
  306. void cleanup(void){
  307.     
  308.     SetUpA4();
  309.     UseResFile(gOurResFile);
  310.     ChangedResource(gQualRsrc);
  311.     WriteResource(gQualRsrc);        /* we're assuming that we can write to the tools rsrc fork */
  312.     HUnlock(gQualRsrc);
  313.     ReleaseResource(gQualRsrc);
  314.     RestoreA4();
  315.     }
  316.     
  317.  
  318. /* gets quality form global */
  319. void recordSound(PVAL  pret, PVAL  parg){
  320.     OSErr            err;
  321.     short            rsrcID;
  322.     Handle            sndH;
  323.     Point                pt={50,60};
  324.     short            sndResFile;
  325.     short            vRefNum;
  326.     GrafPtr            savedport;
  327.     short            savedResFile;
  328.     short            tempFileRefNum;
  329.     
  330.     SetUpA4();
  331.     sndH=nil;
  332.     sndResFile=-1;
  333.     SETPT(&pt, 40, 50);
  334.     gGlobalStr[0]=0;
  335.     SetReturnStr(gGlobalStr);/*whatever is in this sting will be returned when tool's function returns*/
  336.     if ((parg[0].flag != STRING )&&( parg[1].flag != STRING ))
  337.         DoErr(12);
  338.     
  339.     if (!InputManagerInstalled()){
  340.         getErrString(0, siWrongRecVersion,gGlobalStr);
  341.         goto recordReturnPoint;
  342.         }
  343.  
  344.     GetPort(&savedport);
  345.     savedResFile=CurResFile();
  346.     
  347.     SetPort(gOurPort);
  348.     UseResFile(gOurResFile);
  349.             
  350.     GetVol(nil,&vRefNum);
  351.     tempFileRefNum=0;
  352.     err=FSOpen(FILENAME, vRefNum, &tempFileRefNum);    /* note:  we don't need the fileNum just check
  353.                                                     to see if it's open*/
  354.     if (err==-49){
  355.         getErrString(err, siNeedClosedSpeadSheet,gGlobalStr);
  356.         goto recordReturnPoint;
  357.         }
  358.     else if (err==-54){
  359.         getErrString(err, siAlreadyInUse,gGlobalStr);
  360.         goto recordReturnPoint;
  361.         }
  362.     else if (err){
  363.         getErrString(err, siFileErr,gGlobalStr);
  364.         goto recordReturnPoint;
  365.         }
  366.     /*else    we opened it.  This means we can write to it's rsrc fork.
  367.             well close it when we're done!*/
  368.     CreateResFile(FILENAME);  /*Does nothing if file already exists*/
  369.     if ((sndResFile=OpenRFPerm(FILENAME,vRefNum,fsRdWrPerm))==-1){
  370.         getErrString(ResError(), siResErr,gGlobalStr);
  371.         goto recordReturnPoint;
  372.         }
  373.  
  374.     sndH=NewHandle(MaxBlock()*3/4-20000);    /* leave some free space, Note:  I don't know how much. */
  375.     if (sndH==nil){
  376.         getErrString(MemError(), siMemErr,gGlobalStr);
  377.         goto recordReturnPoint;
  378.         }
  379.     InitCursor();
  380.     HLock((Handle)gQualRsrc);    /* don't let it move*/
  381.     err=SndRecord(nil, pt, *(OSType *)StripAddress(*gQualRsrc), &sndH);    /* allow other quals?*/
  382.     HUnlock((Handle)gQualRsrc);    /* don't let it move*/
  383.  
  384.     if (err == -128){ /*user cancelled*/
  385.         getErrString(0,siCancelled,gGlobalStr);
  386.         goto recordReturnPoint;
  387.         }
  388.     else if (err){
  389.         getErrString(err, siSoundRecErr,gGlobalStr);
  390.         goto recordReturnPoint;
  391.         }    /* delete any existing sound with the same name*/
  392.  
  393.     delete1Sound((StringPtr )SNDNAME,sndResFile);
  394.  
  395.     while((rsrcID=UniqueID('snd '))<5000); /* get a unique resource rsrcID > 5000 */
  396.  
  397.     AddResource(sndH, 'snd ', rsrcID, SNDNAME);
  398.     if (err=ResError()){
  399.         getErrString(err, siResErr,gGlobalStr);
  400.         goto recordReturnPoint;
  401.         }
  402.     UpdateResFile(sndResFile);
  403.     ReleaseResource(sndH);
  404.     sndH=nil;
  405.  
  406. recordReturnPoint:
  407.     if (sndH){
  408.         DetachResource(sndH);
  409.         DisposHandle(sndH);
  410.         sndH=nil;    /* leave it memory?*/
  411.         }
  412.     if (sndResFile!=-1)
  413.         CloseResFile(sndResFile);
  414.     if (tempFileRefNum)
  415.         FSClose(tempFileRefNum);
  416.     SetPort(savedport);
  417.     UseResFile(savedResFile);
  418.     RestoreA4();
  419.     }
  420.  
  421.  
  422. void deleteSound(PVAL  pret, PVAL  parg){
  423.     short        savedResFile;
  424.     short        sndResFile;
  425.     short        vRefNum,tempFileRefNum;
  426.     OSErr        err;
  427.         
  428.     SetUpA4();
  429.     sndResFile=-1;
  430.     gGlobalStr[0]=0;
  431.     SetReturnStr(gGlobalStr);/*whatever is in this sting will be returned when tool's function returns*/
  432.     
  433.     if ((parg[0].flag != STRING )&&( parg[1].flag != STRING ))
  434.         DoErr(12);
  435.  
  436.     savedResFile=CurResFile();    
  437.     tempFileRefNum=0;
  438.     GetVol(nil,&vRefNum);
  439.     err=FSOpen(FILENAME, vRefNum, &tempFileRefNum);    /* note:  we don't need the fileNum just check
  440.                                                     to see if it's open*/
  441.     if (err==-49){
  442.         getErrString(err, siNeedClosedSpeadSheet,gGlobalStr);
  443.         goto deleteReturnPoint;
  444.         }
  445.     else if (err==-54){
  446.         getErrString(err, siAlreadyInUse,gGlobalStr);
  447.         goto deleteReturnPoint;
  448.         }
  449.     else if (err){
  450.         getErrString(err, siFileErr,gGlobalStr);
  451.         goto deleteReturnPoint;
  452.         }
  453.     /*else    we opened it.  This means we can write to it's rsrc fork.
  454.             well close it when we're done!*/
  455.  
  456.     if ((sndResFile=OpenRFPerm(FILENAME,vRefNum,fsRdWrPerm))==-1){
  457.         getErrString(ResError(), siResErr,gGlobalStr);
  458.         goto deleteReturnPoint;
  459.         }
  460.  
  461.  
  462.     delete1Sound((StringPtr)SNDNAME,sndResFile);
  463.     
  464. deleteReturnPoint:
  465.     if (sndResFile!=-1)
  466.         CloseResFile(sndResFile);
  467.     if (tempFileRefNum)
  468.         FSClose(tempFileRefNum);
  469.     UseResFile(savedResFile);
  470.     RestoreA4();
  471.     }
  472.  
  473.  
  474. void getSoundQuality(PVAL  pret, PVAL  parg){
  475.     short        savedResFile;
  476.     OSErr        err;
  477.         
  478.     SetUpA4();
  479.     
  480.     gGlobalStr[0]=0;
  481.     SetReturnStr(gGlobalStr);/*whatever is in this sting will be returned when tool's function returns*/
  482.         
  483.     /* put the global quality into the return string */
  484.     BlockMove(StripAddress(*gQualRsrc),&(gGlobalStr[1]),4L);    /* convert OSType to pascal String */
  485.     gGlobalStr[0]=4;
  486.  
  487.     }
  488.  
  489. /*  check that the quality passed to this routine is in ('good','betr','best') and set the global gQualRsrc to it.
  490. Note that the values 'good', 'betr', 'best' are hard coded and may present incompatalities with future sound input
  491. drivers*/
  492. void setSoundQuality(PVAL  pret, PVAL  parg){
  493.     short            savedResFile;
  494.     short            count;
  495.     OSType            tempQual;
  496.  
  497.     SetUpA4();
  498.  
  499.     if (parg[0].flag != STRING )
  500.         DoErr(12);
  501.  
  502.     savedResFile=CurResFile();
  503.     UseResFile(gOurResFile);
  504.     
  505.     if (parg[0].val.string[0] != 4)  /* should be only 4 characters long for an OSType */
  506.         getErrString(0,siBadQuality,gGlobalStr);
  507.  
  508.     BlockMove(&(parg[0].val.string[1]),&tempQual,4L); /* load the quality into a temp variable */
  509.     /* since an OSType is actually a long, compare longs to see it they match */
  510.     switch (tempQual) {
  511.         case ('good'):
  512.         case ('betr'):
  513.         case ('best'):
  514.             **gQualRsrc=tempQual; /* valid quality so assign it to our global */
  515.             break;
  516.         default:
  517.             getErrString(0,siBadQuality,gGlobalStr); /* not a valid quality so return an error*/
  518.         }
  519.  
  520.     UseResFile(savedResFile);
  521.     RestoreA4();
  522.     }
  523.  
  524. void copyPict(PVAL     pret,PVAL     parg){
  525.     OSErr            err;
  526.     Handle            pictH;
  527.     long                size;
  528.     short             savedResFile;
  529.  
  530.     SetUpA4();
  531.     pictH=nil;
  532.  
  533.     if ( parg[0].flag != STRING )
  534.         DoErr(12);
  535.  
  536.     savedResFile=CurResFile();
  537.     UseResFile(gOurResFile);
  538.     pictH=Get1NamedResource('PICT',parg[0].val.string);
  539.     if (pictH==nil){
  540.         SetResLoad(false);
  541.         pictH=Get1NamedResource('PICT',parg[0].val.string);
  542.         SetResLoad(true);
  543.         if (pictH==nil){
  544.             SetErr(8);        /* insufficient data error*/
  545.             }
  546.         else{
  547.             SetErr(21);        /* Out-o-mem*/
  548.             }
  549.         goto pictReturnPoint;    /* complete normally*/
  550.         }
  551.     size=GetHandleSize(pictH);
  552.     HLock(pictH);
  553.     if (err=ZeroScrap())
  554.         goto pictReturnPoint;
  555.     if (size & 1)    /* make sure not odd (by checking bit 0) */
  556.         size++;
  557.     err=PutScrap(size,'PICT',*pictH);
  558.     err=SystemEdit(3);    
  559.     
  560. pictReturnPoint:
  561.     if (pictH){
  562.         HUnlock(pictH);
  563.         ReleaseResource(pictH);
  564.         }
  565.     UseResFile(savedResFile);
  566.     RestoreA4();
  567.     }        
  568.  
  569. void getSounds(PVAL  pret, PVAL  parg){
  570.     OSErr            err;
  571.     short            rsrcID;
  572.     OSType            rsrcType;
  573.     Handle            sndH;
  574.     short            sndResFile;
  575.     short            vRefNum;
  576.     short            tempFileRefNum,savedResFile;
  577.     
  578.     
  579.     SetUpA4();
  580.     sndH=nil;
  581.     sndResFile=-1;
  582.     savedResFile=CurResFile();
  583.  
  584.     gGlobalStr[0]=0;
  585.     SetReturnStr(gGlobalStr);/*whatever is in this sting will be returned when tool's function returns*/
  586.  
  587.     if (parg[0].flag != STRING )
  588.         DoErr(12);
  589.     UseResFile(gOurResFile);
  590.  
  591.     GetVol(nil,&vRefNum);
  592.     err=FSOpen(FILENAME, vRefNum, &tempFileRefNum);    /* note:  we don't need the fileNum just check
  593.                                                     to see if it's open*/
  594.     if (err==-49){
  595.         getErrString(err, siNeedClosedSpeadSheet,gGlobalStr);
  596.         goto getSoundsReturnPoint;
  597.         }
  598.     else if (err==-54){
  599.         getErrString(err, siAlreadyInUse,gGlobalStr);
  600.         goto getSoundsReturnPoint;
  601.         }
  602.     else if (err){
  603.         getErrString(err, siFileErr,gGlobalStr);
  604.         goto getSoundsReturnPoint;
  605.         }
  606.     /*else    we opened it.  This means we can write to it's rsrc fork.
  607.             well close it when we're done!*/
  608.  
  609.     if ((sndResFile=OpenRFPerm(FILENAME,vRefNum,fsRdWrPerm))==-1){
  610.         getErrString(ResError(), siResErr,gGlobalStr);
  611.         goto getSoundsReturnPoint;
  612.         }
  613.  
  614.     SetResLoad(false); /* don't need to load in data to delete it. */
  615.     sndH=(Handle)Get1IndResource('snd ',gSndIndex);
  616.     gSndIndex++;
  617.     if (sndH){
  618.         GetResInfo(sndH, &rsrcID, &rsrcType, &gGlobalStr);    /* get the rsrcID */
  619.         }
  620.     /*else we return an empty string*/        
  621.     SetResLoad(true);
  622.  
  623. getSoundsReturnPoint:
  624.     if (sndResFile!=-1)
  625.         CloseResFile(sndResFile);
  626.     if (tempFileRefNum)
  627.         FSClose(tempFileRefNum);
  628.  
  629.     UseResFile(savedResFile);
  630.     RestoreA4();
  631.     }
  632.  
  633. /* param 0 is the prompt, 1-4 is the file type filter */
  634. void sfGetFile(PVAL  pret,PVAL  parg){
  635.     SFReply            sf;
  636.     Point                pt;
  637.     SFTypeList        sflist;
  638.     short            count;
  639.     GrafPtr            savedport;
  640.     short            savedResFile;
  641.     
  642.     SetUpA4();
  643.     GetPort(&savedport);
  644.     savedResFile=CurResFile();
  645.     SetPort(gOurPort);
  646.     
  647.     if ((parg[0].flag != STRING) &&(parg[1].flag != STRING) &&(parg[2].flag != STRING) && 
  648.         (parg[3].flag != STRING) &&(parg[4].flag != STRING))
  649.             DoErr(12);
  650.     count=0;
  651.     while((parg[count+1].val.string)[0] != 0){    /* copy the data into sflist struct, while it's not empty */
  652.             count++;
  653.             BlockMove((Ptr)&((parg[count].val.string)[1]),(Ptr)&(sflist[count-1]),4L);
  654.             }
  655.     if (count == 0 )
  656.         count=-1;     /* show all files */
  657.     
  658.     ParamText(nil,nil,nil,parg[0].val.string);  /* Use position 4 to minimize impact on Bat*/
  659.     pt=CenteredDLOG(14000);  /* center the SFGet dialog*/
  660.     SFPGetFile(pt,parg[0].val.string,nil,count,sflist,nil,&sf,14000,nil);
  661.     
  662.     ParamText(nil,nil,nil,"\p");             /*zero it out*/
  663.     pret[0].flag = STRING;
  664.     if (sf.good){
  665.         GetFullPathName(sf,gGlobalStr);
  666.         }
  667.     else{
  668.         gGlobalStr[0] = '\0';
  669.         }    
  670.     pret[0].val.string =(char *) StripAddress(gGlobalStr);
  671.     SetPort(savedport);
  672.     UseResFile(savedResFile);
  673.     RestoreA4();
  674.     }
  675.  
  676.  
  677. ROUT    myROUT;
  678.  
  679. #ifdef Debugging
  680. _main(void){
  681. #else
  682. main(void){
  683. #endif Debugging
  684.     ROUT *PROut;
  685.     
  686.     RememberA0();
  687.     SetUpA4();
  688.     
  689. /* Tell about our Functions*/
  690.     PROut=&myROUT;
  691.     PROut->nrout = numfuncs;
  692.     PROut->exitfunc = (ProcPtr)cleanup;
  693.  
  694. /*  Load in function names from our rsrc fork.  Note that these strings MUST be placed into
  695. seperate globals since Resolve doesn't copy them into there own memory*/
  696.     GetIndString(gFuncName[0], sRoutineNames, siRecordRoutine);    
  697.     GetIndString(gFuncName[1], sRoutineNames, siDeleteRoutine);    
  698.     GetIndString(gFuncName[2], sRoutineNames, siSetQualityRoutine);    
  699.     GetIndString(gFuncName[3], sRoutineNames, siGetQualityRoutine);    
  700.     GetIndString(gFuncName[4], sRoutineNames, siCopyPICTRoutine);    
  701.     GetIndString(gFuncName[5], sRoutineNames, siGetSoundsRoutine);    
  702.     GetIndString(gFuncName[6], sRoutineNames, siMySFGetFile);    
  703.  
  704. /* Set info that Resolve uses when calling the function*/
  705.     PROut->relts[0].pfunc = (ProcPtr)recordSound; /* location */
  706.     PROut->relts[0].name  = gFuncName[0];/* name of function in Resolve script*/
  707.     PROut->relts[0].narg  =    2;    /* number of parameters that the function requires*/
  708.  
  709.     PROut->relts[1].pfunc = (ProcPtr) deleteSound;
  710.     PROut->relts[1].name  = gFuncName[1];
  711.     PROut->relts[1].narg  =    2;
  712.  
  713.     PROut->relts[2].pfunc = (ProcPtr)setSoundQuality;
  714.     PROut->relts[2].name  = gFuncName[2];
  715.     PROut->relts[2].narg  =    1;
  716.  
  717.     PROut->relts[3].pfunc = (ProcPtr)getSoundQuality;
  718.     PROut->relts[3].name  = gFuncName[3];
  719.     PROut->relts[3].narg  =    0;
  720.  
  721.     PROut->relts[4].pfunc = (ProcPtr)copyPict;
  722.     PROut->relts[4].name  = gFuncName[4];
  723.     PROut->relts[4].narg  =    1;
  724.  
  725.     PROut->relts[5].pfunc = (ProcPtr)getSounds;
  726.     PROut->relts[5].name  = gFuncName[5];
  727.     PROut->relts[5].narg  =    1;
  728.  
  729.     PROut->relts[6].pfunc = (ProcPtr)sfGetFile;
  730.     PROut->relts[6].name  = gFuncName[6];    /* later make these be able to be read in from the rsrc fork */
  731.     PROut->relts[6].narg  =    5;
  732.  
  733. /* init globals*/
  734.     gOurResFile=CurResFile();
  735.     InitGraf(&thePort);
  736.     GetPort(&gOurPort);
  737.  
  738.     /* install our qual global */
  739.     gSndIndex=1;
  740.     gQualRsrc=nil;
  741.     gQualRsrc=(OSType **)GetResource('qual', kQualID);
  742.     HNoPurge((Handle)gQualRsrc); /*leave it around */
  743.     RestoreA4();
  744.     asm{
  745.         MOVEA.L        0X316, A1;
  746.         MOVEA.L        4(A1), A0;
  747.         MOVE.L        PROut, 0xE(A0);
  748.         }
  749.     }
  750.  
  751.  
  752. #ifdef Debugging
  753. void InitMac(void){
  754.     MoreMasters();
  755.     MoreMasters();
  756.     MaxApplZone();
  757.     
  758.     SetResLoad(true);
  759.     /*InitGraf(&thePort);             general setup */
  760.     /*InitResources();*/
  761.     InitFonts();
  762.     FlushEvents(everyEvent, 0);
  763.     InitWindows();
  764.     InitMenus();
  765.     TEInit();
  766.     InitDialogs(0L);
  767.     InitCursor();
  768.     }
  769.  
  770. main(){
  771.     VAL    dummy;
  772.     Boolean     b;
  773.     short    parent;
  774.     OSErr    err;
  775.     Str255    str="\pMacHog";
  776.     
  777.     _main();
  778.     InitMac();
  779.  
  780.     /*dummy.val.string=gFuncName2;
  781.     dummy.flag=STRING;
  782.     copyPict(&dummy, &dummy);*/
  783.     Debugger();
  784.     
  785.     }
  786. #endif Debugging
  787.